package com.ninong.ker.workflow.service.impl;

import com.google.common.collect.Lists;
import com.ninong.ker.admin.domain.FwGroupData;
import com.ninong.ker.admin.service.FwGroupDataService;
import com.ninong.ker.admin.service.dto.CompleteDTO;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.ProcessDefinition;
import com.google.common.collect.Maps;
import com.ninong.ker.admin.service.RoleService;
import com.ninong.ker.admin.service.TaskService;
import com.ninong.ker.admin.service.dto.ActTaskDTO;
import com.ninong.ker.common.auth.SecurityAdmin;
import com.ninong.ker.common.user.OnlineUser;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.model.payloads.StartProcessPayload;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@org.apache.dubbo.config.annotation.Service(version = "1.0.0")
public class TaskServiceImpl implements TaskService {

//    private static final String TASK_NEED = "NEED";
    private static final String TASK_DONE = "DONE";
    @Autowired
    private org.activiti.engine.TaskService taskService;

    @Autowired
    private SecurityAdmin securityAdmin;

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;

    @Reference(version = "1.0.0", check = false)
    private RoleService roleService;

    @Reference(version = "1.0.0", check = false)
    private FwGroupDataService fwGroupDataService;

    @Override
    public Map<String, Object> listPage(ActTaskDTO dto, String token) {
        Map<String, Object> map = Maps.newHashMap();
        if (StringUtils.equalsAnyIgnoreCase(TASK_DONE, dto.getTaskType())) {
            map = getTaskDoneMap(dto, token);
        } else {
            map = getTaskNeedMap(dto, token);
        }
        return map;
    }

    /**
     * 已办
     *
     * @param dto
     * @param token
     * @return
     */
    private Map<String, Object> getTaskDoneMap(ActTaskDTO dto, String token) {


        return null;
    }

    /**
     * 待办
     *
     * @param dto
     * @param token
     * @return
     */
    private Map<String, Object> getTaskNeedMap(ActTaskDTO dto, String token) {
        List<ActTaskDTO> list = Lists.newArrayList();
        OnlineUser user = securityAdmin.currentUser(token);
        List<String> roles = roleService.listTreeByUserId(user.getId());
        // 使用版本6.x中的接口
        TaskQuery taskQuery = taskService.createTaskQuery();
        taskQuery = taskQuery.or().taskCandidateOrAssigned(user.getId(), roles).taskOwner(user.getId()).endOr().orderByTaskCreateTime().desc();
        List<Task> tasks = taskQuery.listPage((dto.getCurrentPage() - 1) * dto.getPageSize(), dto.getPageSize());
        long totalItems = taskQuery.count();
        if (totalItems != 0) {
            Set<String> processInstanceIdIds = tasks.parallelStream().map(t -> t.getProcessInstanceId()).collect(Collectors.toSet());
            List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().processInstanceIds(processInstanceIdIds).list();
            List<ActTaskDTO> actTaskDTOS = tasks.stream()
                    .map(t -> new ActTaskDTO(t, processInstanceList.parallelStream().filter(pi -> t.getProcessInstanceId().equals(pi.getId())).findAny().get(), fwGroupDataService.get(t.getBusinessKey())))
                    .collect(Collectors.toList());
            list.addAll(actTaskDTOS);
        }
        Map<String, Object> map = Maps.newHashMap();
        map.put("list", list);
        map.put("total", totalItems);
        return map;
    }

    @Override
    public Map<String, Object> insert(String title, FwGroupData entity) {
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(title,entity.getId());
        Map<String, Object> map = Maps.newHashMap();
        map.put("instanceId", processInstance.getId());
        return map;
    }

    @Override
    public void applyTask(CompleteDTO dto) {
//        String comment = dto.getComment();
//        Boolean flag = dto.getFlag();
//        Map<String, Object> variables = taskService.getVariables(dto.getId());
//        Map<String, Object> map = Maps.newHashMap();
//        map.put("flag", flag);
//        map.put("comment", comment);
//        // 判断节点是否已经拒绝过一次了
//        Object needend = variables.get("needend");
//        if (needend != null && (boolean) needend && (!flag)) {
//            map.put("needfinish", -1); //结束
//        } else {
//            if (flag) {
//                map.put("needfinish", 1);//通过下一个节点
//            } else {
//                map.put("needfinish", 0);//不通过
//            }
//        }
        taskService.complete(dto.getId());
    }

    public ProcessDefinition processDefinition(String processDefinitionId) {
        List<ProcessDefinition> list = this.repositoryService.createProcessDefinitionQuery().processDefinitionKey(processDefinitionId).orderByProcessDefinitionVersion().asc().list();
        ProcessDefinition processDefinition;
        if (!list.isEmpty()) {
            processDefinition = list.get(0);
        } else {
            processDefinition = repositoryService.getProcessDefinition(processDefinitionId);
        }
        return processDefinition;
    }
}
